package com.ideal.utils;
import com.ideal.core.constant.Constant;
import com.ideal.utils.Empty;
import com.ideal.core.table.ColumnPropertyConverter;
import com.ideal.core.table.TableClassConverter;
import com.ideal.view.settings.TemplateBaseInfo;
import com.ideal.view.settings.TemplateSetting;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 获取数据库相应信息
 */
public class TableBuilder {
    /**
     * 获取列名，列数据类型，列备注(列备注无会导致空指针异常)
     */
    private static String columnSql = "SELECT t1.COLUMN_NAME,t1.DATA_TYPE, t2.COMMENTS FROM user_tab_columns t1, user_col_comments t2  " +
            " WHERE t1.TABLE_NAME=? " +
            " AND t1.TABLE_NAME  =t2.TABLE_NAME " +
            " AND t1.COLUMN_NAME =t2.COLUMN_NAME ";
    /**
     * 查询表的主键列列名
     */
    private static String primarySql = "select column_name from user_cons_columns where table_name = ?" +
            " and constraint_name in( " +
            " select constraint_name from user_constraints where table_name = ? and constraint_type = 'P') ";

    /**
     * 将数据库相关信息封装成TableBuilder
     * @return
     */
    public static TableClassConverter tableClass(String tableName) {
        TemplateSetting setting = TemplateSetting.getInstance();
        TableClassConverter classDesc = new TableClassConverter();
        Connection con = null;
        TemplateBaseInfo info = setting.getInfo();
        try {
            //加载驱动类
            Class.forName(info.getDriverClass());
        }catch (ClassNotFoundException e1) {
            e1.printStackTrace();
        }
        //将各种流放入try()中，将由try来执行close()操作
        try {

            con = DriverManager.getConnection(info.getJdbcUrl(),info.getUser(),info.getPassword());

            PreparedStatement colStatement = con.prepareStatement(columnSql);
            colStatement.setString(1,tableName);
            ResultSet resultSet = colStatement.executeQuery();

            classDesc.setClassName(StringUtils.tableNameFormat(tableName));
            List<ColumnPropertyConverter> list = new ArrayList<>();
            ColumnPropertyConverter propertyDesc = null;

            String pk = null;

            PreparedStatement pkStatement = con.prepareStatement(primarySql);
            pkStatement.setString(1,tableName);
            pkStatement.setString(2,tableName);
            ResultSet rs = pkStatement.executeQuery();
            while (rs.next()){
                pk = rs.getString("column_name");
            }

            while (resultSet.next()) {
                propertyDesc = new ColumnPropertyConverter();
                String columnName = resultSet.getString(1);
                String dataType = resultSet.getString(2);
                String comments = resultSet.getString(3);
                String fullClassName = StringUtils.getFullColumnClassName(dataType);
                if (!fullClassName.startsWith("java.lang.")) {
                    classDesc.getTypes().add(fullClassName);
                }
                if(!Empty.isEmpty(pk)&&pk.equals(columnName)){
                    propertyDesc.setPrimary(true);
                    classDesc.setPkName(StringUtils.columnNameFormat(columnName));
                }else{
                    propertyDesc.setPrimary(false);
                }
                propertyDesc.setClassSimpleName(StringUtils.getSimpleColumnClassName(dataType));
                propertyDesc.setPropertyName(StringUtils.columnNameFormat(columnName));
                propertyDesc.setColumnName(columnName.toUpperCase());
                propertyDesc.setElPropertyName("${"+StringUtils.columnNameFormat(columnName)+"}");
                propertyDesc.setComment(comments);
                propertyDesc.setType(StringUtils.getFullColumnClassName(dataType));
                propertyDesc.setPropertyNameUpCase(StringUtils.columnNameUpperCaseFormat(columnName));
                list.add(propertyDesc);
            }
            classDesc.setPropertyDescList(list);
            return  classDesc;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(con!=null){
                try {
                    con.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}
